#!/usr/bin/env python
from math import cos, pi

from main import main

class Wave:
    """Initially this was called Wave because its main function was to run a
    sine wave it could use to tell constraints how long to be. Now it's just a
    fancy container for Actuator Groups.
    """
    def __init__(self):
        self.actuatorGroups = []
    
    def update(self):
        for group in self.actuatorGroups:
            group.update()
    
    def addActuatorGroup(self):
        group = ActuatorGroup(self)
        self.actuatorGroups.append(group)
        return group
    
    def removeActuatorGroup(self, group):
        for constraint in group.constraints:
            constraint.length = constraint.originalLength
            constraint.refresh()
        self.actuatorGroups.remove(group)

class ActuatorGroup(object):
    def __init__(self, root, variation=0.0, offset=0.0, speed=1.0):
        """Makes the length of a spring vary.
        
        speed = speed, relative to universal counter.
        offset = offset in the timing by which constraints expand
        variation = how much the wave's current amplitude influences constraints
        
        """
        self.root = root
        
        self.constraints = set()
        
        self._variation = variation
        self._offset = offset
        self.speed = speed
    
    def update(self):
        t = cos(main.counter * self.speed + self.offset*pi)
        k = 1.0 + self.variation * t
        for c in self.constraints:
            c.setLength(c.originalLength * k)
    
    def addConstraint(self, constraint):
        constraint.originalLength = constraint.length
        self.constraints.add(constraint)
    
    def removeConstraint(self, constraint):
        if constraint in self.constraints:
            self.constraints.remove(constraint)
            constraint.setLength(constraint.originalLength)
    
    def get_variation(self):
        return self._variation
    def set_variation(self, val):
        self._variation = max(0.0, val)
        self._variation = min(1.0, val)
    
    def get_offset(self):
        return self._offset
    def set_offset(self, val):
        self._offset = max(0.0, val)
        self._offset = min(1.0, val)
    
    variation = property(get_variation, set_variation)
    offset = property(get_offset, set_offset)